package com.ruoyi.stock2.service.impl;

import java.io.*;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.List;

import com.ruoyi.common.annotation.DataSource;
import com.ruoyi.common.enums.DataSourceType;
import com.ruoyi.stock2.domain.DownTradedataSchedule;
import com.ruoyi.stock2.domain.STOCK;
import com.ruoyi.stock2.domain.TRADEDATA;
import com.ruoyi.stock2.service.IDownTradedataScheduleService;
import com.ruoyi.stock2.service.ISTOCKService;
import com.ruoyi.stock2.service.ITRADEDATAService;
import com.ruoyi.stock2.utils.DateUtils2;
import com.ruoyi.stock2.utils.OtherUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.stock2.mapper.SEQ2SEQLOGMapper;
import com.ruoyi.stock2.domain.SEQ2SEQLOG;
import com.ruoyi.stock2.service.ISEQ2SEQLOGService;
import com.ruoyi.common.core.text.Convert;
import org.springframework.transaction.annotation.Transactional;

/**
 * 深度学习时序模型生成记录Service业务层处理
 *
 * @author ruoyi
 * @date 2020-04-13
 */
@Service
public class SEQ2SEQLOGServiceImpl implements ISEQ2SEQLOGService
{
    private static final Logger log = LoggerFactory.getLogger(SEQ2SEQLOGServiceImpl.class);
    @Autowired(required = false)
    private ITRADEDATAService itradedataService;

    @Autowired(required = false)
    private ISTOCKService istockService;

    @Autowired(required = false)
    private SEQ2SEQLOGMapper sEQ2SEQLOGMapper;

    @Autowired
    private IDownTradedataScheduleService downTradedataScheduleService;
    /**
     * 查询深度学习时序模型生成记录
     *
     * @param id 深度学习时序模型生成记录ID
     * @return 深度学习时序模型生成记录
     */
    @Override
    public SEQ2SEQLOG selectSEQ2SEQLOGById(Long id)
    {
        return sEQ2SEQLOGMapper.selectSEQ2SEQLOGById(id);
    }

    /**
     * 查询深度学习时序模型生成记录列表
     *
     * @param sEQ2SEQLOG 深度学习时序模型生成记录
     * @return 深度学习时序模型生成记录
     */
    @Override
    public List<SEQ2SEQLOG> selectSEQ2SEQLOGList(SEQ2SEQLOG sEQ2SEQLOG)
    {
        return sEQ2SEQLOGMapper.selectSEQ2SEQLOGList(sEQ2SEQLOG);
    }

    /**
     * 新增深度学习时序模型生成记录
     *
     * @param sEQ2SEQLOG 深度学习时序模型生成记录
     * @return 结果
     */
    @Override
    public int insertSEQ2SEQLOG(SEQ2SEQLOG sEQ2SEQLOG)
    {
        return sEQ2SEQLOGMapper.insertSEQ2SEQLOG(sEQ2SEQLOG);
    }

    /**
     * 修改深度学习时序模型生成记录
     *
     * @param sEQ2SEQLOG 深度学习时序模型生成记录
     * @return 结果
     */
    @Override
    public int updateSEQ2SEQLOG(SEQ2SEQLOG sEQ2SEQLOG)
    {
        return sEQ2SEQLOGMapper.updateSEQ2SEQLOG(sEQ2SEQLOG);
    }

    /**
     * 删除深度学习时序模型生成记录对象
     *
     * @param ids 需要删除的数据ID
     * @return 结果
     */
    @Override
    public int deleteSEQ2SEQLOGByIds(String ids)
    {
        return sEQ2SEQLOGMapper.deleteSEQ2SEQLOGByIds(Convert.toStrArray(ids));
    }

    /**
     * 删除深度学习时序模型生成记录信息
     *
     * @param id 深度学习时序模型生成记录ID
     * @return 结果
     */
    @Override
    public int deleteSEQ2SEQLOGById(Long id)
    {
        return sEQ2SEQLOGMapper.deleteSEQ2SEQLOGById(id);
    }

    /**
     * 生成时序训练集
     *
     * @param sEQ2SEQLOG
     * @return
     */
    @Override
    @Transactional
    @DataSource(value = DataSourceType.SLAVE)
    public int createSEQ2SEQTrain(SEQ2SEQLOG sEQ2SEQLOG) {
        sEQ2SEQLOG = sEQ2SEQLOGMapper.selectSEQ2SEQLOGById(sEQ2SEQLOG.getId());
        System.err.println(sEQ2SEQLOG.toString());
        sEQ2SEQLOG.setRemarks("000000");
        sEQ2SEQLOG.setCreateDatetime(DateUtils2.formatDateToString(new Date(), "yyyy-MM-dd HH:mm:ss"));
        updateSEQ2SEQLOG(sEQ2SEQLOG);

        File fileFolder = new File(sEQ2SEQLOG.getUrl() + DateUtils2.formatDateToString(sEQ2SEQLOG.getLatestTradeDate(), "yyyy-MM-dd") );
        if(!fileFolder.exists()){
			fileFolder.mkdirs();
		}

        List<STOCK> list = istockService.selectSTOCKList(null);
        for (STOCK stock : list) {
            TRADEDATA tradedata = new TRADEDATA();
            tradedata.setSymbol(stock.getSymbol());
            //小于设定值 getLatestTradeDate
            tradedata.setDatetime(sEQ2SEQLOG.getLatestTradeDate());

            List<TRADEDATA> listtrades = itradedataService.selectTradedataListForSeq2SeqTrainData(tradedata);
            File file = new File(sEQ2SEQLOG.getUrl() + DateUtils2.formatDateToString(sEQ2SEQLOG.getLatestTradeDate(), "yyyy-MM-dd") +"/" + stock.getSymbol() + ".txt");
            BufferedWriter writer = null;
            try {
                if(!file.exists()){
                    file.createNewFile();
                }else{
                    file.delete();
                    file.createNewFile();
                }
                writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file, true), "utf-8"));

                writer.write( "SYMBOL,NAME,DATETIME,CLOSEPRICE,ZHANGFU\r\n");
                for (int i = 0; i < listtrades.size(); i++) {
                    TRADEDATA tradedata1 = listtrades.get(i);
                    String dateTimeString = getLocalDateStr(tradedata1.getDatetime(),"yyyy-MM-dd");
                    String sb = tradedata1.getSymbol() + "," + stock.getName() + "," + dateTimeString + "," + tradedata1.getCloseprice() + "," + tradedata1.getZhangfu();
                    if (sb != null) {
                        writer.write(sb + "\r\n");
                    }
                }
                writer.flush();
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            } catch (IOException e1) {
                e1.printStackTrace();
            } finally {

                if(writer != null) {
                    try {
                        writer.close();
                        WeakReferenceTool weakReferenceTool = new WeakReferenceTool();
                        weakReferenceTool.setListtrades(listtrades);
                        new Thread(weakReferenceTool).start();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }

        }



        return 0;
    }

    /**
     * 生成时序模型
     *
     * @param sEQ2SEQLOG
     * @return
     */
    @Override
    public int createSEQ2SEQModel(SEQ2SEQLOG sEQ2SEQLOG) {

        sEQ2SEQLOG = sEQ2SEQLOGMapper.selectSEQ2SEQLOGById(sEQ2SEQLOG.getId());
        String symbol = sEQ2SEQLOG.getRemarks();

        List<STOCK> list = istockService.selectSTOCKList(null);
        for (STOCK stock : list) {
            if(stock.getSymbol().compareTo(symbol)<=0){
                continue;
            }
            //停止生成模型
            String seq2seqModelStop = downTradedataScheduleService.selectDownTradedataScheduleByName("seq2seqModelStop").getValue();
            /* 更新股票单 如果更新了，处在下载数据阶段，那么不再更新股票单*/
            if("1".equals(seq2seqModelStop)){
               break;
            }

            log.warn("开始生成"+stock.getSymbol()+"模型...");
            TRADEDATA tradedata = new TRADEDATA();
            tradedata.setSymbol(stock.getSymbol());
            //小于设定值 getLatestTradeDate
            tradedata.setDatetime(sEQ2SEQLOG.getLatestTradeDate());
            List<TRADEDATA> listtrades = itradedataService.selectTradedataListForSeq2SeqTrainData(tradedata);
            if(listtrades.size()>500){
                try {
                    OtherUtils.exec("python f:/seq2seqstockTrain_main2.py -i " + stock.getSymbol() + " -o " + DateUtils2.formatDateToString(sEQ2SEQLOG.getLatestTradeDate(), "yyyy-MM-dd"));
                    log.warn("完成"+stock.getSymbol()+"模型");
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }else{
                log.warn("listtrades.size()<=500，symbol=" + stock.getSymbol()+"，LatestTradeDate="+DateUtils2.formatDateToString(sEQ2SEQLOG.getLatestTradeDate(), "yyyy-MM-dd") );
            }
            sEQ2SEQLOG.setRemarks(stock.getSymbol());
            sEQ2SEQLOGMapper.updateSEQ2SEQLOG(sEQ2SEQLOG);
            listtrades = null;
        }

        String seq2seqModelStop = downTradedataScheduleService.selectDownTradedataScheduleByName("seq2seqModelStop").getValue();
        /* 更新股票单 如果更新了，处在下载数据阶段，那么不再更新股票单*/
        if("1".equals(seq2seqModelStop)){
            DownTradedataSchedule downTradedataSchedule = new DownTradedataSchedule();
            downTradedataSchedule.setName("seq2seqModelStop");
            downTradedataSchedule.setValue("0");
            downTradedataScheduleService.updateDownTradedataSchedule(downTradedataSchedule);
        }

        return 0;
    }

    /**
     * 预测股票的时序结果
     *
     * @param symbol
     * @return
     */
    @Override
    public int predSEQ2SEQ(String symbol) {
        return 0;
    }


    public String getLocalDateStr(Date date, String formatter) {

        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(formatter);
        Instant instant = date.toInstant();
        ZoneId zoneId = ZoneId.systemDefault();
        LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, zoneId);
        String dateStr = dateTimeFormatter.format(localDateTime);

        return dateStr;
    }
}
